package com.gjy.mongod.codec;

import com.gjy.mongod.domain.Goods;
import com.gjy.mongod.domain.WorkOrder;
import org.bson.BsonReader;
import org.bson.BsonType;
import org.bson.BsonWriter;
import org.bson.codecs.Codec;
import org.bson.codecs.DecoderContext;
import org.bson.codecs.EncoderContext;
import org.bson.codecs.configuration.CodecProvider;
import org.bson.codecs.configuration.CodecRegistry;

import java.math.BigDecimal;

/**
 * @author 宫静雨
 * @version 1.0
 * @since 2023-10-16 14:20:22
 */
public class GoodsProvider implements CodecProvider {

    @Override
    public <T> Codec<T> get(Class<T> aClass, CodecRegistry codecRegistry) {
        if (aClass == Goods.class) {
            return (Codec<T>) new GoodsCodec();
        }
        return null;
    }

    private static class GoodsCodec implements Codec<Goods> {

        @Override
        public Goods decode(BsonReader reader, DecoderContext context) {
            Goods goods = new Goods();
            reader.readStartDocument();
            while (reader.readBsonType() != BsonType.END_OF_DOCUMENT) {
                String s = reader.readName();
                switch (s) {
                    case "_id":
                        goods.setId(reader.readInt64());
                        break;
                    case "name":
                        goods.setName(reader.readString());
                        break;
                    case "price":
                        goods.setPrice(BigDecimal.valueOf(reader.readDouble()));
                        break;
                    case "stock":
                        goods.setStock(reader.readInt32());
                        break;
                    case "type":
                        goods.setType(reader.readString());
                        break;
                    default:
                        reader.skipValue();
                }
            }
            reader.readEndDocument();
            return goods;
        }

        @Override
        public void encode(BsonWriter writer, Goods value, EncoderContext encoderContext) {
            writer.writeStartDocument();
            if (value.getId() != null) {
                writer.writeInt64("_id", value.getId());
            }
            writer.writeString("name", value.getName());
            writer.writeDouble("price", value.getPrice().doubleValue());
            writer.writeInt32("stock", value.getStock());
            writer.writeString("type", value.getType());


            writer.writeStartArray("kind");
            value.getKind().forEach(writer::writeString);
            writer.writeEndArray();

            writer.writeStartDocument("workOrder");
            WorkOrder workOrder = value.getWorkOrder();
            writer.writeInt64("id", workOrder.getId());
            writer.writeString("creator", workOrder.getCreator());
            writer.writeInt32("age", workOrder.getAge());
            writer.writeDouble("price", workOrder.getPrice().doubleValue());
            writer.writeEndDocument();

            writer.writeEndDocument();
        }

        @Override
        public Class<Goods> getEncoderClass() {
            return Goods.class;
        }
    }

}
